package com.cn.auth.jwt.signers;

import lombok.Getter;

import javax.crypto.KeyGenerator;
import javax.crypto.Mac;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.Base64;


/**
 * @Author SHANGGUAN
 **/
@Getter
public class HmacSign implements Signature {


    private final Mac mac;

    public static void main(String[] args) {
        HmacSign asd = new HmacSign("JWT_SECRET");
        boolean verify = asd.verify("eyJhbGciOiJPQXV0bzIiLCJ0eXAiOiJKV1QifQ==",
                "eyJhdWQiOiJMb2dpbiIsInN1YiI6Ik9BdXRvMiIsIm5iZiI6MTcyNzQ2MDg0MDg5MywiaXNzIjoiYWRtaW4iLCJleHAiOjE3Mjc0NjgwMzk4OTMsImlhdCI6MTcyNzQ2MDgzOTg5MywianRpIjoiMSJ9",
                "sz8RYWGmFR74aD9+4sswNezad2bbaQ7qv3cIj5mxVt4=");
        System.out.println(verify);
    }
    public HmacSign(SecretKey secretKey) {
        try {
            mac = Mac.getInstance("HmacSHA256");
            mac.init(secretKey);
        } catch (NoSuchAlgorithmException | InvalidKeyException e) {
            throw new RuntimeException(e);
        }

    }

    public HmacSign(String secret) {
        try {
            mac = Mac.getInstance("HmacSHA256");
            SecretKeySpec secretKey = new SecretKeySpec(secret.getBytes(), "HmacSHA256");
            mac.init(secretKey);
        } catch (NoSuchAlgorithmException | InvalidKeyException e) {
            throw new RuntimeException(e);
        }

    }

    public HmacSign() {
        try {
            KeyGenerator keyGenerator = KeyGenerator.getInstance("HmacSHA256");
            SecretKey secretKey = keyGenerator.generateKey();
            mac = Mac.getInstance("HmacSHA256");
            mac.init(secretKey);
        } catch (NoSuchAlgorithmException | InvalidKeyException e) {
            throw new RuntimeException(e);
        }
    }



    @Override
    public String sign(String headerBase64, String payloadBase64) {
        String format = String.format("%s.%s", headerBase64, payloadBase64);
        mac.update(format.getBytes());
        byte[] bytes = mac.doFinal();
        return Base64.getEncoder().encodeToString(bytes);
    }

    @Override
    public boolean verify(String headerBase64, String payloadBase64, String signBase64) {
        String format = String.format("%s.%s", headerBase64, payloadBase64);
        mac.update(format.getBytes());
        byte[] bytes = mac.doFinal();
        String hexBinary =  Base64.getEncoder().encodeToString(bytes);
        return hexBinary.equals(signBase64);
    }
}
